package com.mengxj.classes;

import com.common.collection.Student;
import com.common.lambda.Animal;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * java 运行
 * 编译   .java -> .class
 * 运行  运行
 * .class 肯定包含类的类型，属性，和方法  所以通过.class文件就可以调用该文件的任何方法/属性
 *
 * .class 文件在Java中用Class表示
 *
 * class：关键字  Class是类型，表示.class
 *
 * 获取Class对象的方法：
 * 1，用Class 的 静态方法forName获取，传入全称限定名
 *      全称限定名：就是  包名.类名   比如当前类：com.mengxj.classes.ClassDemo
 * 2，可以用Object对象的getClass方法获取。也就是  任何对象.getClass()
 * 3，类名.class 也可以获取Class对象
 *
 * 通过Class操作方法的技术，称之为 '反射'
 *
 * 以下操作 com.common.collection.Student
 * @author mengxj
 */
public class ClassDemo {

    @SortType("v")
    private List<Integer> list = Arrays.asList(1,4,3,1,3);

    public static void main(String[] args) throws Exception {
        ClassDemo demo = new ClassDemo();
        demo.sortByAnno();
    }

    void sortByAnno() throws Exception {
        Class<ClassDemo> cls = ClassDemo.class;
        Field field = cls.getDeclaredField("list");
        SortType sortType = field.getDeclaredAnnotation(SortType.class);
        String value = sortType.value();
        if("a".equals(value)){
            sort1();
        }else {
            sort2();
        }
    }

    void sort1(){
        list.sort((i, j) -> i - j);
        list.forEach(System.out::println);
    }

    void sort2(){
        list.sort((j, i) -> i - j);
        list.forEach(System.out::println);
    }

    /**
     * 判断对象obj是否可以转换为Animal
     * @param obj 被判断的对象
     */
    static void isConvert1(Object obj){
        if(!(obj instanceof Animal)){
            System.out.print("不");
        }
        System.out.println("可以");
    }

    static void isConvert2(Object obj){
        Animal.class.cast(obj);
    }

    static void demo1() throws Exception {
        ClassDemo demo = new ClassDemo();
        Student student1 = demo.createStudent1();
        Student student2 = demo.createStudent1();
        //反射 调用
        //1，获取class对象
        Class<?> cls = student1.getClass();
        //2，通过 cls 获取该类的所有方法
        Method[] methods = cls.getDeclaredMethods();
//        for (Method method: methods){
//            System.out.println(method.getName());
//        }
        //3，无参数：调用方法 invoke
        Method
        //有参数例子：想要调用set方法
        method = cls.getDeclaredMethod("setName", String.class);
        method.invoke(student1, "张三");
        method = cls.getDeclaredMethod("getName");
        //student1.getName
        Object obj = method.invoke(student1);
        System.out.println(obj);
        //student2.getName
        obj = method.invoke(student2);
        System.out.println(obj);
        method = cls.getDeclaredMethod("print");
        method.setAccessible(true);
        method.invoke(student1);
    }

    private Student createStudent1(){
        Student student = new Student();
        student.setAge(12);
        student.setAddress("aaa");
        student.setName("bbb");
        return student;
    }
}
